package com.appspot.checkflames.filter;

import static com.appspot.checkflames.constants.CheckFlamesConstants.ACCESS_TOKEN_PARAM;
import static com.appspot.checkflames.constants.CheckFlamesConstants.AMPERSAND_SIGN;
import static com.appspot.checkflames.constants.CheckFlamesConstants.EQUAL_SIGN;
import static com.appspot.checkflames.constants.CheckFlamesConstants.QUESTION_MARK;

import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.StringTokenizer;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.google.appengine.api.urlfetch.HTTPMethod;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;

public class LoginFilter implements Filter {

	private static final String FACEBOOK_REDIRECT_URL_PARAM = "facebook_redirect_uri";
	private static String FACEBOOK_REDIRECT_URL;
	
	private static final String CLIENT_SECRET_PARAM= "client_secret";
	private static String CLIENT_SECRET;
	
	private static final String CLIENT_ID_PARAM = "client_id";
	private static String CLIENT_ID;
	
	private static final String REDIRECT_URL_PARAM = "redirect_uri";
	private static String REDIRECT_URL;
	
	private static final String SUCCESS_REDIRECT_URL_PARAM = "success_redirect_url";
	private static String SUCCESS_REDIRECT_URL;
	
	private static final String CODE_PARAM = "code";
	
	private static final Logger LOGGER = Logger.getLogger(LoginFilter.class);
	
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	public void doFilter(ServletRequest pRequest, ServletResponse pResponse,
			FilterChain pChain) throws IOException, ServletException {
		String code = pRequest.getParameter(CODE_PARAM);
		LOGGER.info("CODE : " + code);
		
		HttpServletResponse response = (HttpServletResponse) pResponse;
		
		if(code != null && code.length() > 0) {
			StringBuilder builder = new StringBuilder(FACEBOOK_REDIRECT_URL);
			builder.append(QUESTION_MARK);
			builder.append(CLIENT_ID_PARAM);
			builder.append(EQUAL_SIGN);
			builder.append(CLIENT_ID);
			builder.append(AMPERSAND_SIGN);
			builder.append(REDIRECT_URL_PARAM);
			builder.append(EQUAL_SIGN);
			builder.append(URLEncoder.encode(REDIRECT_URL,"UTF-8"));
			builder.append(AMPERSAND_SIGN);
			builder.append(CLIENT_SECRET_PARAM);
			builder.append(EQUAL_SIGN);
			builder.append(CLIENT_SECRET);
			builder.append(AMPERSAND_SIGN);
			builder.append(CODE_PARAM);
			builder.append(EQUAL_SIGN);
			builder.append(URLEncoder.encode(code,"UTF-8"));
			
			String url = builder.toString();
			HTTPRequest httpRequest = new HTTPRequest(new URL(url), HTTPMethod.GET);
			HTTPResponse httpResponse = URLFetchServiceFactory.getURLFetchService().fetch(httpRequest);
			String accessMap = new String(httpResponse.getContent());
			
			StringTokenizer tokenizer = new StringTokenizer(accessMap,"&");
			String accessTokenMap = tokenizer.nextToken();
			//String expiresMap = tokenizer.nextToken();
			StringTokenizer accessTokenKeyMap = new StringTokenizer(accessTokenMap,"=");
			String accessTokenKey = accessTokenKeyMap.nextToken();
			String accessToken = accessTokenKeyMap.nextToken();
			LOGGER.info("ACCESS TOKEN : " + accessMap);
			if(!accessTokenKey.equals(ACCESS_TOKEN_PARAM)) {
				LOGGER.error("Invalid access token response!");
				return;
			} 
			HttpServletRequest request = (HttpServletRequest) pRequest;
			//StringTokenizer expiresKeyMap = new StringTokenizer(expiresMap,"=");
			//String expiresKey = expiresKeyMap.nextToken();
			//String expires = expiresKeyMap.nextToken();
			request.getSession().setAttribute(ACCESS_TOKEN_PARAM, accessToken);
			//request.getSession().setMaxInactiveInterval(Integer.parseInt(expires));
			LOGGER.info("ACCESS TOKEN : " + accessToken);
			
			response.sendRedirect(SUCCESS_REDIRECT_URL);
			return;
		} 
		String accessToken = pRequest.getParameter(ACCESS_TOKEN_PARAM);
		LOGGER.info("Access Token : "+accessToken);
		response.sendRedirect(SUCCESS_REDIRECT_URL);
	}

	public void init(FilterConfig pConfig) throws ServletException {
		FACEBOOK_REDIRECT_URL = pConfig.getInitParameter(FACEBOOK_REDIRECT_URL_PARAM);
		REDIRECT_URL = pConfig.getInitParameter(REDIRECT_URL_PARAM);
		CLIENT_ID = pConfig.getInitParameter(CLIENT_ID_PARAM);
		CLIENT_SECRET = pConfig.getInitParameter(CLIENT_SECRET_PARAM);
		SUCCESS_REDIRECT_URL = pConfig.getInitParameter(SUCCESS_REDIRECT_URL_PARAM);
	}

}
